﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace WordStat
{
    /// <summary>
    /// Interaction logic for TreeGridControl.xaml
    /// </summary>
    public partial class TreeGridControl : UserControl
    {
        public TreeGridControl()
        {
            InitializeComponent();
        }

        private void AddFileClick(object sender, RoutedEventArgs e)
        {
        }

        private FileContainer _fileContainer;

        private void TasksClick(object sender, RoutedEventArgs e)
        {
            var tSrv = new Tasks.TaskService();
            tSrv.ShowTasks();
        }

        private ArticleService _dataSrv;

        public void SetArticleService(ArticleService dataSrv)
        {
            _dataSrv = dataSrv;

            var data = _dataSrv.GetItem();

            _treeView.Items.Add(data);
        }

        private void _treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            var selectedItem = _treeView.SelectedItem as TreeViewItem;

            if (selectedItem == null)
                return;

            _selectedItem = selectedItem;

            UpdateDataGrid();
        }

        private void _dataGrid_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
        {
            var dg = e.DetailsElement as DataGrid;

            if (dg == null)
                return;

            var wordRecord = e.Row.Item as WordRecord;

            if (wordRecord == null)
                return;

            var wordData = _dataSrv.GetArticles(wordRecord.Text, _currentSource);

            dg.ItemsSource = wordData.Select(w => new ArticleRecord { Title = w.Key.Title, Url = w.Key.Url, WordCount = w.Value, WordText = wordRecord.Text, ArticleText = w.Key.Text }).ToList();
        }

        private void _nestedDataGrid_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
        {
            var dockPanel = e.DetailsElement as DockPanel;

            if (dockPanel == null)
                return;

            var articleRecord = e.Row.Item as ArticleRecord;

            if (articleRecord == null)
                return;

            dockPanel.Children.Clear();

            var texts = GetParts(articleRecord.ArticleText, articleRecord.WordText, articleRecord.WordCount);

            foreach (var text in texts)
            {
                var myFlowDoc = new FlowDocument();

                // Add paragraphs to the FlowDocument.
                myFlowDoc.Blocks.Add(new Paragraph(new Run(text.Text)));
                var myRichTextBox = new RichTextBox { Document = myFlowDoc };
                myRichTextBox.Width = 350;

                var startPos = myRichTextBox.Document.ContentStart.GetPositionAtOffset(text.Start);
                var endPos = myRichTextBox.Document.ContentStart.GetPositionAtOffset(text.Start + text.Length);

                if (startPos != null && endPos != null)
                {
                    var textRange = new TextRange(startPos, endPos);

                    textRange.ApplyPropertyValue(TextElement.FontWeightProperty, FontWeights.Bold);
                }

                DockPanel.SetDock(myRichTextBox, Dock.Top);

                dockPanel.Children.Add(myRichTextBox);

                /*
                var txtBlock = new TextBox();
                txtBlock.Width = 350;
                txtBlock.TextWrapping = TextWrapping.Wrap;

                DockPanel.SetDock(txtBlock, Dock.Top);

                txtBlock.Text = text.Text;

                txtBlock.Select(text.Start, text.Length); 
                //txtBlock.SelectionLength = text.Length;

                dockPanel.Children.Add(txtBlock);*/
            }
        }

        private sealed class TextRec
        {
            public string Text { get; set; }

            public int Start { get; set; }

            public int Length { get; set; }
        }

        private List<TextRec> GetParts(string articleText, string word, int wordCount)
        {
            var res = new List<TextRec>();
            int i = 0;

            int startIndex = 0;

            do
            {
                var index = articleText.IndexOf(word, startIndex, StringComparison.InvariantCultureIgnoreCase);

                if (index == -1)
                    break;

                var start = index - _charCount;

                if (start < 0)
                    start = 0;

                var end = index + _charCount;

                if (end >= articleText.Length)
                    end = articleText.Length - 1;

                var length = end - start;

                if (length < 0)
                    break;

                var article = new TextRec { Text = articleText.Substring(start, length) };

                var startWordIndex = article.Text.IndexOf(word, StringComparison.InvariantCultureIgnoreCase);

                if (startWordIndex == -1)
                    break;

                res.Add(new TextRec { Text = articleText.Substring(start, length), Start = startWordIndex + 2, Length = word.Length });

                startIndex = index + 1;

                if (startIndex >= articleText.Length)
                    break;

            } while (i < wordCount);

            return res;
        }

        private void _sourceComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var selectedItem = _sourceComboBox.SelectedItem as ComboBoxItem;

            if (selectedItem == null)
                return;

            var selectedText = selectedItem.Content.ToString();

            if (selectedText == _currentSource)
                return;

            _currentSource = selectedText;

            UpdateDataGrid();
        }

        private void UpdateDataGrid()
        {
            var data = _dataSrv.GetDataFrom(_selectedItem, _pageNumber, 200, GetCurSource());

            var list = data.Select(iter => new WordRecord { Text = iter.Key, WordCount = iter.Value }).ToList();

            _dataGrid.DataContext = list;
        }

        private string GetCurSource()
        {
            if (_currentSource == null)
                return string.Empty;

            if (_currentSource.Equals("All", StringComparison.InvariantCultureIgnoreCase))
                return string.Empty;

            return _currentSource;
        }

        private string _currentSource = string.Empty;
        private TreeViewItem _selectedItem;

        private void OnHyperLink(object sender, RoutedEventArgs e)
        {
            var destination = ((Hyperlink)e.OriginalSource).NavigateUri;
            Process.Start(destination.ToString());

        }

        private void _prevBtn_Click(object sender, RoutedEventArgs e)
        {
            _isTextChanging = true;

            if (_pageNumber != 0)
                _pageNumber--;

            _pageNumberTextBlock.Text = _pageNumber.ToString();

            UpdateDataGrid();

            _isTextChanging = false;
        }

        private void _prev10Btn_Click(object sender, RoutedEventArgs e)
        {
            _isTextChanging = true;

            _pageNumber -= 10;

            if (_pageNumber < 0)
                _pageNumber = 0;

            _pageNumberTextBlock.Text = _pageNumber.ToString();

            UpdateDataGrid();

            _isTextChanging = false;
        }

        private void _nextBtn_Click(object sender, RoutedEventArgs e)
        {
            _isTextChanging = true;

            _pageNumber += 1;

            _pageNumberTextBlock.Text = _pageNumber.ToString();

            UpdateDataGrid();

            _isTextChanging = false;
        }

        private void _next10Btn_Click(object sender, RoutedEventArgs e)
        {
            _isTextChanging = true;

            _pageNumber += 10;

            _pageNumberTextBlock.Text = _pageNumber.ToString();

            UpdateDataGrid();

            _isTextChanging = false;
        }

        private int _pageNumber;
        private int _charCount = 150;
        private bool _isTextChanging;

        private void _pageNumberTextBlock_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (_isTextChanging)
                return;

            int pageNumber;

            if(!int.TryParse(_pageNumberTextBlock.Text, out pageNumber))
                return;

            _pageNumber = pageNumber;

            UpdateDataGrid();
        }
    }

    public sealed class WordRecord
    {
        public string Text { get; set; }

        public int WordCount { get; set; }
    }

    public sealed class ArticleRecord
    {
        public string Title { get; set; }

        public string Url { get; set; }

        public string ArticleText { get; set; }

        public int WordCount { get; set; }

        public string WordText { get; set; }
    }
}
